import logging
import os.path
import time
from logging import handlers

import colorlog

from settings import LOG_PATH
from utils.config import rfc


class Logger(object):
    """日志类"""

    log_conf = rfc.get_log_config()

    def __init__(self):
        # 创建logger对象
        self._logger = logging.getLogger()

    @property
    def log_file(self):
        """日志文件

        :return:
        """
        # 创建日志存放目录
        os.makedirs(LOG_PATH, exist_ok=True)

        # 生成日志文件名并返回该路径
        now = time.strftime('%Y-%m-%d %H-%M-%S')
        return os.path.join(LOG_PATH, '%s.log' % now)

    def console_handler(self):
        """日志输出到控制台

        :return:
        """
        # 创建控制台实例
        sh = colorlog.StreamHandler()

        # 设置控制台输出的日志格式
        formatter = colorlog.ColoredFormatter(fmt=self.log_conf.get('log_cli_format'),
                                              datefmt=self.log_conf.get('log_cli_date_format'))
        sh.setFormatter(fmt=formatter)

        # 设置控制台输出的日志级别
        log_cli_level = self.log_conf.get('log_cli_level')
        log_cli_level = logging.getLevelName(log_cli_level.upper())
        sh.setLevel(log_cli_level)

        # 加载控制台实例到logger对象
        self._logger.addHandler(sh)

    def file_handler(self):
        """日志输出到文件

        :return:
        """
        '''
        创建一个文件实例, 如果文件不存在则会自动创建, 
        文件是默认以追加的方式进行写入
        按照时间自动分割日志文件, 间隔1天切割一次
        保留每天最新的3个文件备份, 最先创建的文件会被自动删除
        另外防止出现乱码, encoding 参数设置为utf-8
        '''
        fh = handlers.TimedRotatingFileHandler(filename=self.log_file,
                                               when='D', interval=1,
                                               backupCount=3, encoding='utf-8')

        # 设置向文件输出的日志格式
        formatter = logging.Formatter(fmt=self.log_conf.get('log_file_format'),
                                      datefmt=self.log_conf.get('log_file_date_format'))
        fh.setFormatter(fmt=formatter)

        # 设置向文件输出的日志级别
        log_file_level = self.log_conf.get('log_file_level')
        log_file_level = logging.getLevelName(log_file_level.upper())
        fh.setLevel(log_file_level)

        # 加载文件实例到logger对象
        self._logger.addHandler(fh)

    @property
    def logger(self):
        """对外的logger使用对象

        :return:
        """
        # 如果logger对象已存在handle对象则直接返回，防止handler重复
        if self._logger.handlers:
            return self._logger

        # 向logger对象添加文件句柄
        self.file_handler()

        # 如果日志输出到控制台
        if self.log_conf.get('log_cli'):
            # 向logger对象添加控制台句柄
            self.console_handler()

        # 设置日志输出等级总开关
        log_level = self.log_conf.get('log_level')
        log_level = logging.getLevelName(log_level.upper())
        self._logger.setLevel(log_level)

        # 返回日志类的logger私有属性
        return self._logger


# 单例模式
logger = Logger().logger

if __name__ == '__main__':
    logger.debug('----调试信息[debug]----')
    logger.info('----有用的信息[info]----')
    logger.warning('----告警信息[warning]----')
    logger.error('----错误信息[error]----')
    logger.critical('----严重错误信息[critical]----')
